#include "msg_sciApi.h"

/* define */
#define CREAT_2_BYTESGROUP(data1,data0) ((UINT16)data1<<8)+((UINT32)data0)
#define CREAT_3_BYTESGROUP(data2,data1,data0) ((UINT32)data2<<16)+((UINT32)data1<<8)+((UINT32)data0)
#define CREAT_4_BYTESGROUP(data3,data2,data1,data0) ((UINT32)data3<<24)+((UINT32)data2<<16)+((UINT32)data1<<8)+((UINT32)data0)

#define BYTE_1st_OF_BYTESGROUP(data) ((UINT8)data)
#define BYTE_2nd_OF_BYTESGROUP(data) ((UINT8)(data>>8))
#define BYTE_3rd_OF_BYTESGROUP(data) ((UINT8)(data>>16))
#define BYTE_4th_OF_BYTESGROUP(data) ((UINT8)(data>>24))

/* arrays */
static const UINT32 SCI_NumPowerOf2[]=
{
    0x00000001,0x00000002,0x00000004,0x00000008,
    0x00000010,0x00000020,0x00000040,0x00000080,
    0x00000100,0x00000200,0x00000400,0x00000800,
    0x00001000,0x00002000,0x00004000,0x00008000,
    0x00010000,0x00020000,0x00040000,0x00080000,
    0x00100000,0x00200000,0x00400000,0x00800000,
    0x01000000,0x02000000,0x04000000,0x08000000,
    0x10000000,0x20000000,0x40000000,0x80000000
};


/*****************************************************************************
 * Function Name: l_u32 SCI_pow_int(l_u8 n)
 * Description: the n power of 2
 * Param:   n power
 * Return:  compute result 
 * Author:  
 *****************************************************************************/
static UINT32 SCI_pow_int(UINT8 n)
{
//    UINT8 i;
    UINT32 mul=1;
    
    /*if(n==0) return mul;
    for(i=0;i<n;i++) mul*=2;*/
    
    //mul<<=n;/* shift */
    mul=SCI_NumPowerOf2[n];/* table */
    return mul;       
}

/*****************************************************************************/
/**
 * Function Name: 
 * Description:  sci signal read/write functions
 *
 * Param:   none
 * Return:  none
 * Author:  AF
 * *****************************************************************************/ 

/* Possible loss of data */ 
#pragma MESSAGE DISABLE C2705
  
/* sci signal read functions */
BOOL s_bool_rd(SCI_RX_MSG_S *ptr, UINT8 lsbPos, UINT8 bitSize)
{
    UINT8 signal=0;
    signal=(*((ptr->Data)+(lsbPos/8)));
    signal>>=(lsbPos%8);
    signal&=(UINT8)(SCI_pow_int(bitSize)-1);
    return (BOOL)signal;
}

UINT8 s_u8_rd(SCI_RX_MSG_S *ptr, UINT8 lsbPos, UINT8 bitSize)
{
    UINT16 signal=0;
    /* signal in 1 Byte */
    if((lsbPos/8)==((lsbPos+bitSize-1)/8))
    {
        signal=(*((ptr->Data)+(lsbPos/8)));
        signal>>=(UINT8)(lsbPos%8);
        signal&=(UINT8)(SCI_pow_int(bitSize)-1);       
    }
    /* signal in 2 Bytes */
    else
    {
        signal=CREAT_2_BYTESGROUP((*((ptr->Data)+(lsbPos/8)-1)),
                                  (*((ptr->Data)+(lsbPos/8))));
        signal>>=(UINT8)(lsbPos%8);
        signal&=(UINT8)(SCI_pow_int(bitSize)-1);
    }
    return (UINT8)signal;    
}

UINT16 s_u16_rd(SCI_RX_MSG_S *ptr, UINT8 lsbPos, UINT8 bitSize)
{   /* This funtion operation time is 24us */
    UINT32 signal=0;
    /* signal in 2 Bytes */
    if((lsbPos/8+1)==((lsbPos+bitSize-1)/8))
    {
        signal=CREAT_2_BYTESGROUP((*((ptr->Data)+(lsbPos/8)-1)),
                                  (*((ptr->Data)+(lsbPos/8))));
        signal>>=(lsbPos%8);
        signal&=(UINT16)(SCI_pow_int(bitSize)-1);    
    }
    /* signal in 3 Bytes */
    else
    {
        signal=CREAT_3_BYTESGROUP((*((ptr->Data)+(lsbPos/8)-2)),
                                  (*((ptr->Data)+(lsbPos/8)-1)),
                                  (*((ptr->Data)+(lsbPos/8))));    
        signal>>=(lsbPos%8);
        signal&=(UINT16)(SCI_pow_int(bitSize)-1);
    }
    return (UINT16)signal;
}

UINT32 s_u32_rd(SCI_RX_MSG_S *ptr, UINT8 lsbPos, UINT8 bitSize)
{   /* This funtion operation time is 40us */
    UINT32 signal=0;
    /* signal in 3 Bytes */
    if((lsbPos/8+2)==((lsbPos+bitSize-1)/8))
    {
        signal=CREAT_3_BYTESGROUP((*((ptr->Data)+(lsbPos/8)-2)),
                                  (*((ptr->Data)+(lsbPos/8)-1)),
                                  (*((ptr->Data)+(lsbPos/8))));
        signal>>=(lsbPos%8);
        signal&=(UINT32)(SCI_pow_int(bitSize)-1);    
    }
    /* signal in 4 Bytes */
    else
    {
        signal=CREAT_4_BYTESGROUP((*((ptr->Data)+(lsbPos/8)-3)),
                                  (*((ptr->Data)+(lsbPos/8)-2)),
                                  (*((ptr->Data)+(lsbPos/8)-1)),
                                  (*((ptr->Data)+(lsbPos/8))));
       signal>>=(lsbPos%8);
       signal&=(UINT32)(SCI_pow_int(bitSize)-1);                                   
    }
    return (UINT32)signal;
    /* not support signal in 5 Bytes */
}

/* sci signal write functions */
void s_bool_wr(SCI_TX_MSG_S *ptr, UINT8 lsbPos, UINT8 bitSize, BOOL v)
{
    (void)bitSize;
    if((v!=0)&&(v!=1)) return;
    if((v&0x01)!=0)
    {
        (*((ptr->Data)+(lsbPos/8)))|=(UINT8)SCI_pow_int(lsbPos%8); 
    }
    else
    {
        (*((ptr->Data)+(lsbPos/8)))&=~(UINT8)SCI_pow_int(lsbPos%8);
    }       
}

void s_u8_wr(SCI_TX_MSG_S *ptr, UINT8 lsbPos, UINT8 bitSize, UINT8 v)
{
    UINT8  signalMaskData[2];
    UINT32 signalMask,signal,signalNew;
    
    /* signal in 1 Byte */
    if((lsbPos/8)==((lsbPos+bitSize-1)/8))
    {
        signal=(*((ptr->Data)+(lsbPos/8)));
        
        if(lsbPos%8)
        {
            signalMaskData[0]=(UINT8)SCI_pow_int(lsbPos%8)-1;   
        }
        else
        {
            signalMaskData[0]=0;
        }

        if((lsbPos+bitSize)%8)
        {
            signalMaskData[1]=~(UINT8)((UINT8)SCI_pow_int((lsbPos+bitSize)%8)-1);
        }
        else
        {
            signalMaskData[1]=0;
        }
        
        signalMask=signalMaskData[0]|signalMaskData[1];/* special */
        signal&=signalMask;
        signalNew=v;
        signalNew&=SCI_pow_int(bitSize)-1;
        signalNew<<=(lsbPos%8);
        signal|=signalNew;
        
        (*((ptr->Data)+(lsbPos/8)))=signal;                   
    }
    /* signal in 2 Bytes */
    else
    {
        signal=CREAT_2_BYTESGROUP((*((ptr->Data)+(lsbPos/8)-1)),
                                  (*((ptr->Data)+(lsbPos/8))));
        
        if(lsbPos%8)
        {
            signalMaskData[0]=(UINT8)SCI_pow_int(lsbPos%8)-1;   
        }
        else
        {
            signalMaskData[0]=0;
        }
        
        if((lsbPos+bitSize)%8)
        {
            signalMaskData[1]=~(UINT8)((UINT8)SCI_pow_int((lsbPos+bitSize)%8)-1);
        }
        else
        {
            signalMaskData[1]=0;
        }
        
        signalMask=CREAT_2_BYTESGROUP(signalMaskData[1],signalMaskData[0]);
        signal&=signalMask;
        signalNew=v;
        signalNew&=SCI_pow_int(bitSize)-1;
        signalNew<<=(lsbPos%8);
        signal|=signalNew;
        
        (*((ptr->Data)+(lsbPos/8)-1))=BYTE_2nd_OF_BYTESGROUP(signal); 
        (*((ptr->Data)+(lsbPos/8)))  =BYTE_1st_OF_BYTESGROUP(signal);
    }
}

void s_u16_wr(SCI_TX_MSG_S *ptr, UINT8 lsbPos, UINT8 bitSize, UINT16 v)
{   /*    shift,bitSize=9~16,t=130us~300us */
    /*    table,bitSize=9~16,t=80us~140us */
    /* no cycle,bitSize=9~16,t=26us~34us */
    UINT8  signalMaskData[3];
    UINT32 signalMask,signal,signalNew;
    
    /* signal in 2 Bytes */    
    if((lsbPos/8+1)==((lsbPos+bitSize-1)/8))
    {
        signal=CREAT_2_BYTESGROUP((*((ptr->Data)+(lsbPos/8)-1)),
                                  (*((ptr->Data)+(lsbPos/8))));
                                                                  
        if(lsbPos%8)
        {
            signalMaskData[0]=(UINT8)SCI_pow_int(lsbPos%8)-1;   
        }
        else
        {
            signalMaskData[0]=0;
        }
        
        if((lsbPos+bitSize)%8)
        {
            signalMaskData[1]=~(UINT8)((UINT8)SCI_pow_int((lsbPos+bitSize)%8)-1);
        }
        else
        {
            signalMaskData[1]=0;
        }
       
        signalMask=CREAT_2_BYTESGROUP(signalMaskData[1],signalMaskData[0]);
        signal&=signalMask;
        signalNew=v;
        signalNew&=SCI_pow_int(bitSize)-1;
        signalNew<<=(lsbPos%8);
        signal|=signalNew;
                                  
        (*((ptr->Data)+(lsbPos/8)-1))=BYTE_2nd_OF_BYTESGROUP(signal); 
        (*((ptr->Data)+(lsbPos/8)))  =BYTE_1st_OF_BYTESGROUP(signal);  
    }
    /* signal in 3 Bytes */
    else
    {
        signal=CREAT_3_BYTESGROUP((*((ptr->Data)+(lsbPos/8)-2)),
                                  (*((ptr->Data)+(lsbPos/8)-1)),
                                  (*((ptr->Data)+(lsbPos/8))));                                  
        if(lsbPos%8)
        {
            signalMaskData[0]=(UINT8)SCI_pow_int(lsbPos%8)-1;   
        }
        else
        {
            signalMaskData[0]=0;
        }
        
        signalMaskData[1]=0;
        
        if((lsbPos+bitSize)%8)
        {
            signalMaskData[2]=~(UINT8)((UINT8)SCI_pow_int((lsbPos+bitSize)%8)-1);
        }
        else
        {                           
            signalMaskData[2]=0;
        }
       
        signalMask=CREAT_3_BYTESGROUP(signalMaskData[2],signalMaskData[1],signalMaskData[0]);
        signal&=signalMask;
        signalNew=v;
        signalNew&=SCI_pow_int(bitSize)-1;
        signalNew<<=(lsbPos%8);
        signal|=signalNew;
        
        (*((ptr->Data)+(lsbPos/8)-2))=BYTE_3rd_OF_BYTESGROUP(signal);
        (*((ptr->Data)+(lsbPos/8)-1))=BYTE_2nd_OF_BYTESGROUP(signal); 
        (*((ptr->Data)+(lsbPos/8)))  =BYTE_1st_OF_BYTESGROUP(signal);                     
    }
}

void s_u32_wr(SCI_TX_MSG_S *ptr, UINT8 lsbPos, UINT8 bitSize, UINT32 v)
{   /*    shift,bitSize=17~32,t=400us~650us */
    /*    table,bitSize=17~32,t=210us~380us */
    /* no cycle,bitSize=17~32,t= 38us~46us */
    UINT8  signalMaskData[4];
    UINT32 signalMask,signal,signalNew;
    
    /* signal in 3 Bytes */
    if((lsbPos/8+2)==((lsbPos+bitSize-1)/8))
    {
        signal=CREAT_3_BYTESGROUP((*((ptr->Data)+(lsbPos/8)-2)),
                                  (*((ptr->Data)+(lsbPos/8)-1)),
                                  (*((ptr->Data)+(lsbPos/8)))); 
        if(lsbPos%8)
        {
            signalMaskData[0]=(UINT8)SCI_pow_int(lsbPos%8)-1;   
        }
        else
        {
            signalMaskData[0]=0;
        }
        
        signalMaskData[1]=0;
        
        if((lsbPos+bitSize)%8)
        {
            signalMaskData[2]=~(UINT8)((UINT8)SCI_pow_int((lsbPos+bitSize)%8)-1);
        }
        else
        {                           
            signalMaskData[2]=0;
        }
       
        signalMask=CREAT_3_BYTESGROUP(signalMaskData[2],signalMaskData[1],signalMaskData[0]);
        signal&=signalMask;
        signalNew=v;
        signalNew&=SCI_pow_int(bitSize)-1;
        signalNew<<=(lsbPos%8);
        signal|=signalNew;
        
        (*((ptr->Data)+(lsbPos/8)-2))=BYTE_3rd_OF_BYTESGROUP(signal);
        (*((ptr->Data)+(lsbPos/8)-1))=BYTE_2nd_OF_BYTESGROUP(signal); 
        (*((ptr->Data)+(lsbPos/8)))  =BYTE_1st_OF_BYTESGROUP(signal);
    }
    /* signal in 4 Bytes */
    else
    {
        signal=CREAT_4_BYTESGROUP((*((ptr->Data)+(lsbPos/8)-3)),
                                  (*((ptr->Data)+(lsbPos/8)-2)),
                                  (*((ptr->Data)+(lsbPos/8)-1)),
                                  (*((ptr->Data)+(lsbPos/8)))); 
        if(lsbPos%8)
        {
            signalMaskData[0]=(UINT8)SCI_pow_int(lsbPos%8)-1;   
        }
        else
        {
            signalMaskData[0]=0;
        }
        
        signalMaskData[1]=0;
        signalMaskData[2]=0;
        
        if((lsbPos+bitSize)%8)
        {
            signalMaskData[3]=~(UINT8)((UINT8)SCI_pow_int((lsbPos+bitSize)%8)-1);
        }
        else
        {                           
            signalMaskData[3]=0;
        }
       
        signalMask=CREAT_4_BYTESGROUP(signalMaskData[3],signalMaskData[2],signalMaskData[1],signalMaskData[0]);
        signal&=signalMask;
        signalNew=v;
        signalNew&=SCI_pow_int(bitSize)-1;
        signalNew<<=(lsbPos%8);
        signal|=signalNew;
        
        (*((ptr->Data)+(lsbPos/8)-3))=BYTE_4th_OF_BYTESGROUP(signal);
        (*((ptr->Data)+(lsbPos/8)-2))=BYTE_3rd_OF_BYTESGROUP(signal);
        (*((ptr->Data)+(lsbPos/8)-1))=BYTE_2nd_OF_BYTESGROUP(signal); 
        (*((ptr->Data)+(lsbPos/8)))  =BYTE_1st_OF_BYTESGROUP(signal);      
    }
    /* not support signal in 5 Bytes */
}

/* Possible loss of data */
#pragma MESSAGE WARNING C2705